package com.lambkit.db.hutool;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.Page;
import cn.hutool.db.sql.SqlBuilder;
import com.lambkit.db.*;
import com.lambkit.db.dialect.DialectFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author yangyong(孤竹行)
 */
public class HutoolDb extends HutoolDbOpt<RowData, PageData<RowData>> implements IDb {

    private DataSource dataSource;

    public HutoolDb(DataSource dataSource, String driverName)  {
        super(Db.use(dataSource, driverName), DialectFactory.newDialect(driverName));
        this.dataSource = dataSource;
    }

//    @Override
//    public <T extends RowModel<T>> IRowDao<T> dao(Class<T> clazz) {
//        return new HutoolModelDao<T>(this, clazz);
//    }
//
//    @Override
//    public <T extends IRowData, P extends IPageData<T>> IDbService by(Class<T> rowClazz, Class<P> pageClazz) {
//        return new HutoolDbService(this, rowClazz, pageClazz);
//    }

    public Entity toEntity(RowData record) {
        Entity entity = Entity.create(record.tableName());
        entity.setFieldNames(record.columnNames());
        entity.putAll(record.toMap());
        return entity;
    }

    @Override
    public Connection getConnection() throws SQLException {
        return getDb().getConnection();
    }

    @Override
    public void closeConnection(Connection connection) {
        getDb().closeConnection(connection);
    }

    @Override
    public DataSource getDataSource() {
        return dataSource;
    }

    @Override
    public RowData newRowData() {
        return new RowData();
    }

    @Override
    public PageData newPageData() {
        return new PageData();
    }

    @Override
    public <T extends RowModel<T>> HutoolModelDao dao(Class<T> clazz) {
        return new HutoolModelDao<T>(this, clazz);
    }

    @Override
    public <T extends IRowData, P extends IPageData<T>> HutoolDbService by(Class<T> rowClazz, Class<P> pageClazz) {
        return new HutoolDbService(this, rowClazz, pageClazz);
    }

    @Override
    public PageData<RowData> paginate(Integer pageNumber, Integer pageSize, Sql sqlPara) {
        Page page = new Page(pageNumber, pageSize);
        try {
            SqlBuilder sqlBuilder = SqlBuilder.of(sqlPara.getSql()).addParams(sqlPara.getPara());
            int total = (int) getDb().count(sqlBuilder);
            RowDataPageHandler handler = RowDataPageHandler.create(new PageData(pageNumber, pageSize, total));
            return getDb().page(sqlBuilder, page, handler);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public List<RowData> find(String sql, Object... paras) {
        try {
            return getDb().query(sql, RowDataListHandler.create(), paras);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public RowData findFirst(String sql, Object... paras) {
        try {
            return getDb().query(sql, RowDataHandler.create(), paras);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

}
